<!DOCTYPE html>
<html lang=zh>
<head><meta name="generator" content="Hexo 3.9.0">
    <!-- so meta -->
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="HandheldFriendly" content="True">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta name="description" content="前言之前使用egg写了个简版的软文后台，顺手就是使用了jq去写界面，后来随着功能越来越多，突然就觉得以前写的 jq 越来越难维护，频繁需要去操作 dom，修改各种页面的状态值。于是打算使用vue重构一版，将其组件化，顺手也就把egg换成了，感觉这种简单的后端需求，koa确实已经足够了。因为软文后台涉及到对图片的处理，我们希望后端能提供一个地址去浏览这些已经处理的图片，所以就有了搭建一个静态资源服务">
<meta name="keywords" content="同花顺,nodejs">
<meta property="og:type" content="article">
<meta property="og:title" content="Koa搭建静态资源服务器">
<meta property="og:url" content="https://andyliwr.github.io/2018/05/07/koa_static_file_server/index.html">
<meta property="og:site_name" content="月光倾城的代码小屋">
<meta property="og:description" content="前言之前使用egg写了个简版的软文后台，顺手就是使用了jq去写界面，后来随着功能越来越多，突然就觉得以前写的 jq 越来越难维护，频繁需要去操作 dom，修改各种页面的状态值。于是打算使用vue重构一版，将其组件化，顺手也就把egg换成了，感觉这种简单的后端需求，koa确实已经足够了。因为软文后台涉及到对图片的处理，我们希望后端能提供一个地址去浏览这些已经处理的图片，所以就有了搭建一个静态资源服务">
<meta property="og:locale" content="zh-CN">
<meta property="og:image" content="https://file.lantingshucheng.com/1525692676116.png">
<meta property="og:updated_time" content="2020-01-15T06:30:09.116Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Koa搭建静态资源服务器">
<meta name="twitter:description" content="前言之前使用egg写了个简版的软文后台，顺手就是使用了jq去写界面，后来随着功能越来越多，突然就觉得以前写的 jq 越来越难维护，频繁需要去操作 dom，修改各种页面的状态值。于是打算使用vue重构一版，将其组件化，顺手也就把egg换成了，感觉这种简单的后端需求，koa确实已经足够了。因为软文后台涉及到对图片的处理，我们希望后端能提供一个地址去浏览这些已经处理的图片，所以就有了搭建一个静态资源服务">
<meta name="twitter:image" content="https://file.lantingshucheng.com/1525692676116.png">
    
    
        
          
              <link rel="shortcut icon" href="/images/favicon.ico">
          
        
        
          
            <link rel="icon" type="image/png" href="/images/favicon-192x192.png" sizes="192x192">
          
        
        
          
            <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon.png">
          
        
    
    <!-- title -->
    <title>Koa搭建静态资源服务器</title>
    <!-- styles -->
    <link rel="stylesheet" href="/css/style.css">
    <!-- persian styles -->
    
      <link rel="stylesheet" href="/css/rtl.css">
    
    <!-- rss -->
    
    
</head>

<body class="max-width mx-auto px3 ltr">
    
      <div id="header-post">
  <a id="menu-icon" href="#"><i class="fas fa-bars fa-lg"></i></a>
  <a id="menu-icon-tablet" href="#"><i class="fas fa-bars fa-lg"></i></a>
  <a id="top-icon-tablet" href="#" onclick="$('html, body').animate({ scrollTop: 0 }, 'fast');" style="display:none;"><i class="fas fa-chevron-up fa-lg"></i></a>
  <span id="menu">
    <span id="nav">
      <ul>
         
          <li><a href="/">首页</a></li>
         
          <li><a href="/archives/">归档</a></li>
         
          <li><a href="/search/">搜索</a></li>
         
          <li><a href="/tags/">标签</a></li>
         
          <li><a href="/others/">其他文章</a></li>
        
      </ul>
    </span>
    <br/>
    <span id="actions">
      <ul>
        
        <li><a class="icon" href="/2018/06/11/mongo_auto_backup/"><i class="fas fa-chevron-left" aria-hidden="true" onmouseover="$('#i-prev').toggle();" onmouseout="$('#i-prev').toggle();"></i></a></li>
        
        
        <li><a class="icon" href="/2018/05/03/how_to_write_a_timed_shell/"><i class="fas fa-chevron-right" aria-hidden="true" onmouseover="$('#i-next').toggle();" onmouseout="$('#i-next').toggle();"></i></a></li>
        
        <li><a class="icon" href="#" onclick="$('html, body').animate({ scrollTop: 0 }, 'fast');"><i class="fas fa-chevron-up" aria-hidden="true" onmouseover="$('#i-top').toggle();" onmouseout="$('#i-top').toggle();"></i></a></li>
        <li><a class="icon" href="#"><i class="fas fa-share-alt" aria-hidden="true" onmouseover="$('#i-share').toggle();" onmouseout="$('#i-share').toggle();" onclick="$('#share').toggle();return false;"></i></a></li>
      </ul>
      <span id="i-prev" class="info" style="display:none;">上一篇</span>
      <span id="i-next" class="info" style="display:none;">下一篇</span>
      <span id="i-top" class="info" style="display:none;">返回顶部</span>
      <span id="i-share" class="info" style="display:none;">分享文章</span>
    </span>
    <br/>
    <div id="share" style="display: none">
      <ul>
  <li><a class="icon" href="http://www.facebook.com/sharer.php?u=https://andyliwr.github.io/2018/05/07/koa_static_file_server/"><i class="fab fa-facebook " aria-hidden="true"></i></a></li>
  <li><a class="icon" href="https://twitter.com/share?url=https://andyliwr.github.io/2018/05/07/koa_static_file_server/&text=Koa搭建静态资源服务器"><i class="fab fa-twitter " aria-hidden="true"></i></a></li>
  <li><a class="icon" href="http://www.linkedin.com/shareArticle?url=https://andyliwr.github.io/2018/05/07/koa_static_file_server/&title=Koa搭建静态资源服务器"><i class="fab fa-linkedin " aria-hidden="true"></i></a></li>
  <li><a class="icon" href="https://pinterest.com/pin/create/bookmarklet/?url=https://andyliwr.github.io/2018/05/07/koa_static_file_server/&is_video=false&description=Koa搭建静态资源服务器"><i class="fab fa-pinterest " aria-hidden="true"></i></a></li>
  <li><a class="icon" href="mailto:?subject=Koa搭建静态资源服务器&body=Check out this article: https://andyliwr.github.io/2018/05/07/koa_static_file_server/"><i class="fas fa-envelope " aria-hidden="true"></i></a></li>
  <li><a class="icon" href="https://getpocket.com/save?url=https://andyliwr.github.io/2018/05/07/koa_static_file_server/&title=Koa搭建静态资源服务器"><i class="fab fa-get-pocket " aria-hidden="true"></i></a></li>
  <li><a class="icon" href="http://reddit.com/submit?url=https://andyliwr.github.io/2018/05/07/koa_static_file_server/&title=Koa搭建静态资源服务器"><i class="fab fa-reddit " aria-hidden="true"></i></a></li>
  <li><a class="icon" href="http://www.stumbleupon.com/submit?url=https://andyliwr.github.io/2018/05/07/koa_static_file_server/&title=Koa搭建静态资源服务器"><i class="fab fa-stumbleupon " aria-hidden="true"></i></a></li>
  <li><a class="icon" href="http://digg.com/submit?url=https://andyliwr.github.io/2018/05/07/koa_static_file_server/&title=Koa搭建静态资源服务器"><i class="fab fa-digg " aria-hidden="true"></i></a></li>
  <li><a class="icon" href="http://www.tumblr.com/share/link?url=https://andyliwr.github.io/2018/05/07/koa_static_file_server/&name=Koa搭建静态资源服务器&description="><i class="fab fa-tumblr " aria-hidden="true"></i></a></li>
</ul>

    </div>
    <div id="toc">
      <ol class="toc"><li class="toc-item toc-level-3"><a class="toc-link" href="#前言"><span class="toc-number">1.</span> <span class="toc-text">前言</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Koa-static"><span class="toc-number">2.</span> <span class="toc-text">Koa-static</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#中间件"><span class="toc-number">3.</span> <span class="toc-text">中间件</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#static-js"><span class="toc-number">3.1.</span> <span class="toc-text">static.js</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#router-中新增路由"><span class="toc-number">3.2.</span> <span class="toc-text">router 中新增路由</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#结束"><span class="toc-number">4.</span> <span class="toc-text">结束</span></a></li></ol>
    </div>
  </span>
</div>

    
    <div class="content index py4">
        
        <article class="post" itemscope itemtype="http://schema.org/BlogPosting">
  <header>
    
    <h1 class="posttitle" itemprop="name headline">
        Koa搭建静态资源服务器
    </h1>



    <div class="meta">
      <span class="author" itemprop="author" itemscope itemtype="http://schema.org/Person">
        <span itemprop="name">月光倾城的代码小屋</span>
      </span>
      
    <div class="postdate">
        <time datetime="2018-05-07T17:28:15.000Z" itemprop="datePublished">2018-05-07</time>
    </div>


      

      
    <div class="article-tag">
        <i class="fas fa-tag"></i>
        <a class="tag-link" href="/tags/nodejs/">nodejs</a>, <a class="tag-link" href="/tags/同花顺/">同花顺</a>
    </div>


    </div>
  </header>
  

  <div class="content" itemprop="articleBody">
    <h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>之前使用<code>egg</code>写了个简版的软文后台，顺手就是使用了<code>jq</code>去写界面，后来随着功能越来越多，突然就觉得以前写的 jq 越来越难维护，频繁需要去操作 dom，修改各种页面的状态值。于是打算使用<code>vue</code>重构一版，将其组件化，顺手也就把<code>egg</code>换成了，感觉这种简单的后端需求，<code>koa</code>确实已经足够了。因为软文后台涉及到对图片的处理，我们希望后端能提供一个地址去浏览这些已经处理的图片，所以就有了搭建一个静态资源服务器的需求。博文中用到的代码并非原创，我只是做了一些优化。</p>
<h3 id="Koa-static"><a href="#Koa-static" class="headerlink" title="Koa-static"></a>Koa-static</h3><p>Koa 中间件-<code>koa-static</code>能将项目的某个目录（一般是<code>static</code>或者<code>public</code>目录）的文件映射到路由上，使得这些文件能通过<code>url</code>在浏览器访问到。<br><code>koa-static</code>并没有列出所有文件的功能，想要实现这一功能，只能自己写中间件处理了</p>
<h3 id="中间件"><a href="#中间件" class="headerlink" title="中间件"></a>中间件</h3><p><img src="https://file.lantingshucheng.com/1525692676116.png" alt="最后的效果图"></p>
<h4 id="static-js"><a href="#static-js" class="headerlink" title="static.js"></a>static.js</h4><p>在<code>utils</code>目录下新建静态资源处理的 js—<code>static.js</code></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">'path'</span>)</span><br><span class="line"><span class="keyword">const</span> fs = <span class="built_in">require</span>(<span class="string">'fs'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> mimes = &#123;</span><br><span class="line">  <span class="string">'css'</span>: <span class="string">'text/css'</span>,</span><br><span class="line">  <span class="string">'less'</span>: <span class="string">'text/css'</span>,</span><br><span class="line">  <span class="string">'gif'</span>: <span class="string">'image/gif'</span>,</span><br><span class="line">  <span class="string">'html'</span>: <span class="string">'text/html'</span>,</span><br><span class="line">  <span class="string">'ico'</span>: <span class="string">'image/x-icon'</span>,</span><br><span class="line">  <span class="string">'jpeg'</span>: <span class="string">'image/jpeg'</span>,</span><br><span class="line">  <span class="string">'jpg'</span>: <span class="string">'image/jpeg'</span>,</span><br><span class="line">  <span class="string">'js'</span>: <span class="string">'text/javascript'</span>,</span><br><span class="line">  <span class="string">'json'</span>: <span class="string">'application/json'</span>,</span><br><span class="line">  <span class="string">'pdf'</span>: <span class="string">'application/pdf'</span>,</span><br><span class="line">  <span class="string">'png'</span>: <span class="string">'image/png'</span>,</span><br><span class="line">  <span class="string">'svg'</span>: <span class="string">'image/svg+xml'</span>,</span><br><span class="line">  <span class="string">'swf'</span>: <span class="string">'application/x-shockwave-flash'</span>,</span><br><span class="line">  <span class="string">'tiff'</span>: <span class="string">'image/tiff'</span>,</span><br><span class="line">  <span class="string">'txt'</span>: <span class="string">'text/plain'</span>,</span><br><span class="line">  <span class="string">'wav'</span>: <span class="string">'audio/x-wav'</span>,</span><br><span class="line">  <span class="string">'wma'</span>: <span class="string">'audio/x-ms-wma'</span>,</span><br><span class="line">  <span class="string">'wmv'</span>: <span class="string">'video/x-ms-wmv'</span>,</span><br><span class="line">  <span class="string">'xml'</span>: <span class="string">'text/xml'</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 遍历读取目录内容（子目录，文件名）</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param  <span class="type">&#123;string&#125;</span> </span>reqPath 请求资源的绝对路径</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return <span class="type">&#123;array&#125;</span> </span>目录内容列表</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">walk</span> (<span class="params">reqPath</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">let</span> files = fs.readdirSync(reqPath)</span><br><span class="line"></span><br><span class="line">  <span class="keyword">let</span> dirList = []</span><br><span class="line">  <span class="keyword">let</span> fileList = []</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>, len = files.length; i &lt; len; i++) &#123;</span><br><span class="line">    <span class="keyword">let</span> item = files[i]</span><br><span class="line">    <span class="keyword">let</span> itemArr = item.split(<span class="string">'.'</span>)</span><br><span class="line">    <span class="keyword">let</span> itemMime = (itemArr.length &gt; <span class="number">1</span>) ? itemArr[ itemArr.length - <span class="number">1</span> ] : <span class="string">'undefined'</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (<span class="keyword">typeof</span> mimes[ itemMime ] === <span class="string">'undefined'</span>) &#123;</span><br><span class="line">      dirList.push(files[i])</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      fileList.push(files[i])</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">let</span> result = dirList.concat(fileList)</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> result</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 封装目录内容</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param  <span class="type">&#123;string&#125;</span> </span>url 当前请求的上下文中的url，即ctx.url</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param  <span class="type">&#123;string&#125;</span> </span>reqPath 请求静态资源的完整本地路径</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return <span class="type">&#123;string&#125;</span> </span>返回目录内容，封装成HTML</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">dir</span> (<span class="params">url, reqPath</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 遍历读取当前目录下的文件、子目录</span></span><br><span class="line">  <span class="keyword">let</span> contentList = walk(reqPath)</span><br><span class="line"></span><br><span class="line">  <span class="keyword">let</span> html = <span class="string">`&lt;ul&gt;`</span></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">let</span> [ index, item ] <span class="keyword">of</span> contentList.entries()) &#123;</span><br><span class="line">    html = <span class="string">`<span class="subst">$&#123;html&#125;</span>&lt;li data-index="<span class="subst">$&#123;index&#125;</span>"&gt;&lt;a href="<span class="subst">$&#123;url === <span class="string">'/'</span> ? <span class="string">''</span> : url&#125;</span>/<span class="subst">$&#123;item&#125;</span>"&gt;<span class="subst">$&#123;item&#125;</span>&lt;/a&gt;`</span></span><br><span class="line">  &#125;</span><br><span class="line">  html = <span class="string">`<span class="subst">$&#123;html&#125;</span>&lt;/ul&gt;`</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> html</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 读取文件方法</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param  <span class="type">&#123;string&#125;</span> </span>文件本地的绝对路径</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return <span class="type">&#123;string|binary&#125;</span></span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">file</span> (<span class="params">filePath</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">let</span> content = fs.readFileSync(filePath, <span class="string">'binary'</span>)</span><br><span class="line">  <span class="keyword">return</span> content</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 获取静态资源内容</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param  <span class="type">&#123;object&#125;</span> </span>ctx koa上下文</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param  <span class="type">&#123;string&#125;</span> </span>静态资源目录在本地的绝对路径</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return  <span class="type">&#123;string&#125;</span> </span>请求获取到的本地内容</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">async</span> <span class="function"><span class="keyword">function</span> <span class="title">content</span> (<span class="params">ctx, fullStaticPath</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 封装请求资源的完绝对径</span></span><br><span class="line">  <span class="keyword">let</span> reqPath = path.join(fullStaticPath, ctx.url)</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 判断请求路径是否为存在目录或者文件</span></span><br><span class="line">  <span class="keyword">let</span> exist = fs.existsSync(reqPath)</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 返回请求内容， 默认为空</span></span><br><span class="line">  <span class="keyword">let</span> content = <span class="string">''</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (!exist) &#123;</span><br><span class="line">    <span class="comment">// 如果请求路径不存在，返回404</span></span><br><span class="line">    content = <span class="string">'请求路径不存在！'</span></span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="comment">// 判断访问地址是文件夹还是文件</span></span><br><span class="line">    <span class="keyword">let</span> stat = fs.statSync(reqPath)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (stat.isDirectory()) &#123;</span><br><span class="line">      <span class="comment">// 如果为目录，则渲读取目录内容</span></span><br><span class="line">      content = dir(ctx.url, reqPath)</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="comment">// 如果请求为文件，则读取文件内容</span></span><br><span class="line">      content = <span class="keyword">await</span> file(reqPath)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> content</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 解析资源类型</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">parseMime</span> (<span class="params">url</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">let</span> extName = path.extname(url)</span><br><span class="line">  extName = extName ? extName.slice(<span class="number">1</span>) : <span class="string">'unknown'</span></span><br><span class="line">  <span class="keyword">return</span> mimes[ extName ]</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">  parseMime: parseMime,</span><br><span class="line">  content: content</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>ps: 我把大神的代码合并了下，感觉新建五个 js 还是有点多。另外注意声明中间件的顺序，<code>api</code>的声明应当放在<code>static</code>中间件的前面，否则<code>api</code>声明的路由就都失效了</p>
</blockquote>
<h4 id="router-中新增路由"><a href="#router-中新增路由" class="headerlink" title="router 中新增路由"></a>router 中新增路由</h4><figure class="highlight sqf"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 静态资源服务器</span></span><br><span class="line">router.get(<span class="string">'/static'</span>, async (ctx) =&gt; &#123;</span><br><span class="line">  <span class="comment">// 静态资源目录在本地的绝对路径</span></span><br><span class="line">  let fullStaticPath = path.<span class="built_in">join</span>(<span class="variable">__dirname</span>, <span class="string">'../'</span>)</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 获取静态资源内容，有可能是文件内容，目录，或404</span></span><br><span class="line">  let <span class="variable">_content</span> = await staticUtil.content(ctx, fullStaticPath)</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 解析请求内容的类型</span></span><br><span class="line">  let <span class="variable">_mime</span> = staticUtil.parseMime(ctx.url)</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 如果有对应的文件类型，就配置上下文的类型</span></span><br><span class="line">  <span class="keyword">if</span> (<span class="variable">_mime</span>) &#123;</span><br><span class="line">    ctx.<span class="built_in">type</span> = <span class="variable">_mime</span></span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 输出静态资源内容</span></span><br><span class="line">  <span class="keyword">if</span> (<span class="variable">_mime</span> &amp;&amp; <span class="variable">_mime</span>.indexOf(<span class="string">'image/'</span>) &gt;= <span class="number">0</span>) &#123;</span><br><span class="line">    <span class="comment">// 如果是图片，则用node原生res，输出二进制数据</span></span><br><span class="line">    ctx.res.writeHead(<span class="number">200</span>)</span><br><span class="line">    ctx.res.write(<span class="variable">_content</span>, <span class="string">'binary'</span>)</span><br><span class="line">    ctx.res.end()</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="comment">// 其他则输出文本</span></span><br><span class="line">    ctx.body = <span class="variable">_content</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p>这样当你访问<code>http://localhost:3000/static</code>就能列出位于 static 目录下的所有静态文件了</p>
<h3 id="结束"><a href="#结束" class="headerlink" title="结束"></a>结束</h3><p>只是借鉴然后改了点东西，算是记录下吧…<br>原文请查看<a href="https://chenshenhai.github.io/koa2-note/note/static/server.html" target="_blank" rel="noopener">这里</a></p>

  </div>
  <div class="statement">
    <hr>  
    1. 如果本文帮到了您，不妨点一下右上角的”<i class="fas fa-share-alt"></i>“按钮。<br>
    2. 除非注明，本博文章均为原创，转载请以链接形式标明本文地址。<br>
    3. 如果你有任何疑问，欢迎发送邮件到我的邮箱<a href="mailto:andyliwr@outlook.com">andyliwr@outlook.com<br>
  </div>
</article>


    <div class="blog-post-comments">
        <div id="gitalk_thread">
            <noscript>加载评论需要在浏览器启用 JavaScript 脚本支持。</noscript>
        </div>
    </div>



        
          <div id="footer-post-container">
  <div id="footer-post">

    <div id="nav-footer" style="display: none">
      <ul>
         
          <li><a href="/">首页</a></li>
         
          <li><a href="/archives/">归档</a></li>
         
          <li><a href="/search/">搜索</a></li>
         
          <li><a href="/tags/">标签</a></li>
         
          <li><a href="/others/">其他文章</a></li>
        
      </ul>
    </div>

    <div id="toc-footer" style="display: none">
      <ol class="toc"><li class="toc-item toc-level-3"><a class="toc-link" href="#前言"><span class="toc-number">1.</span> <span class="toc-text">前言</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Koa-static"><span class="toc-number">2.</span> <span class="toc-text">Koa-static</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#中间件"><span class="toc-number">3.</span> <span class="toc-text">中间件</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#static-js"><span class="toc-number">3.1.</span> <span class="toc-text">static.js</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#router-中新增路由"><span class="toc-number">3.2.</span> <span class="toc-text">router 中新增路由</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#结束"><span class="toc-number">4.</span> <span class="toc-text">结束</span></a></li></ol>
    </div>

    <div id="share-footer" style="display: none">
      <ul>
  <li><a class="icon" href="http://www.facebook.com/sharer.php?u=https://andyliwr.github.io/2018/05/07/koa_static_file_server/"><i class="fab fa-facebook fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" href="https://twitter.com/share?url=https://andyliwr.github.io/2018/05/07/koa_static_file_server/&text=Koa搭建静态资源服务器"><i class="fab fa-twitter fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" href="http://www.linkedin.com/shareArticle?url=https://andyliwr.github.io/2018/05/07/koa_static_file_server/&title=Koa搭建静态资源服务器"><i class="fab fa-linkedin fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" href="https://pinterest.com/pin/create/bookmarklet/?url=https://andyliwr.github.io/2018/05/07/koa_static_file_server/&is_video=false&description=Koa搭建静态资源服务器"><i class="fab fa-pinterest fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" href="mailto:?subject=Koa搭建静态资源服务器&body=Check out this article: https://andyliwr.github.io/2018/05/07/koa_static_file_server/"><i class="fas fa-envelope fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" href="https://getpocket.com/save?url=https://andyliwr.github.io/2018/05/07/koa_static_file_server/&title=Koa搭建静态资源服务器"><i class="fab fa-get-pocket fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" href="http://reddit.com/submit?url=https://andyliwr.github.io/2018/05/07/koa_static_file_server/&title=Koa搭建静态资源服务器"><i class="fab fa-reddit fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" href="http://www.stumbleupon.com/submit?url=https://andyliwr.github.io/2018/05/07/koa_static_file_server/&title=Koa搭建静态资源服务器"><i class="fab fa-stumbleupon fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" href="http://digg.com/submit?url=https://andyliwr.github.io/2018/05/07/koa_static_file_server/&title=Koa搭建静态资源服务器"><i class="fab fa-digg fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" href="http://www.tumblr.com/share/link?url=https://andyliwr.github.io/2018/05/07/koa_static_file_server/&name=Koa搭建静态资源服务器&description="><i class="fab fa-tumblr fa-lg" aria-hidden="true"></i></a></li>
</ul>

    </div>

    <div id="actions-footer">
        <a id="menu" class="icon" href="#" onclick="$('#nav-footer').toggle();return false;"><i class="fas fa-bars fa-lg" aria-hidden="true"></i> 菜单</a>
        <a id="toc" class="icon" href="#" onclick="$('#toc-footer').toggle();return false;"><i class="fas fa-list fa-lg" aria-hidden="true"></i> 目录</a>
        <a id="share" class="icon" href="#" onclick="$('#share-footer').toggle();return false;"><i class="fas fa-share-alt fa-lg" aria-hidden="true"></i> 分享</a>
        <a id="top" style="display:none" class="icon" href="#" onclick="$('html, body').animate({ scrollTop: 0 }, 'fast');"><i class="fas fa-chevron-up fa-lg" aria-hidden="true"></i> 返回顶部</a>
    </div>

  </div>
</div>

        
        <footer id="footer">
  <div class="footer-left">
    Copyright &copy; 2020 Dikang Li
  </div>
  <div class="footer-right">
    <nav>
      <ul>
         
          <li><a href="/">首页</a></li>
         
          <li><a href="/archives/">归档</a></li>
         
          <li><a href="/search/">搜索</a></li>
         
          <li><a href="/tags/">标签</a></li>
         
          <li><a href="/others/">其他文章</a></li>
        
      </ul>
    </nav>
  </div>
</footer>

    </div>
</body>
</html>
<!-- styles -->
<link rel="stylesheet" href="/lib/font-awesome/css/all.min.css">
<link rel="stylesheet" href="/lib/justified-gallery/css/justifiedGallery.min.css">
<link rel="stylesheet" href="/lib/fancybox/jquery.fancybox.css">

<link rel="stylesheet" href="https://file.lantingshucheng.com/blog/v3/static/styles/gitalk.css">


<!-- jquery -->
<script src="/lib/jquery/jquery.min.js"></script>
<script src="/lib/justified-gallery/js/jquery.justifiedGallery.min.js"></script>
<script src="/lib/fancybox/jquery.fancybox.pack.js"></script>

<script type="text/javascript" src="https://file.lantingshucheng.com/blog/v3/static/scripts/md5.js"></script>
<script type="text/javascript" src="https://file.lantingshucheng.com/blog/v3/static/scripts/gitalk.min.js"></script>

<script src="/js/main.js"></script>
<!-- search -->

<!-- Google Analytics -->

<!-- Baidu Analytics -->

    <script type="text/javascript">
        var _hmt = _hmt || [];
        (function() {
            var hm = document.createElement("script");
            hm.src = "https://hm.baidu.com/hm.js?7851ca7a86be957be994acb77639a5be";
            var s = document.getElementsByTagName("script")[0];
            s.parentNode.insertBefore(hm, s);
        })();
    </script>

<!-- Disqus Comments -->


  <script type="text/javascript">
    window.onload = function(){
      if (window.location.href.indexOf('andyliwr.github.io') > -1) {
        var gitalk = new Gitalk({
          clientID: 'ad6f70df0c70d2b715f9',
          clientSecret: '40384bee244c1e17dd7c37733d21e9ef669e969c',
          repo: 'Andyliwr.github.io',
          owner: 'Andyliwr',
          admin: ['Andyliwr'],
          id: md5(location.pathname),
          distractionFreeMode: 'true'
        })
        gitalk.render('gitalk_thread')
      }
    }
  </script>


